package crypto.symmetric;

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Random;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class PasswordBaseEncyptionTest {
	public static void main(String[] args) {
		int n = 100;
		String password = "p@assword";
		String input = "hello, welcome you";
		System.out.println("input : " + input);
		String encryptedText = null;

		//
		byte[] salt = new byte[8];
		Random r = new Random();
		r.nextBytes(salt);

		PBEParameterSpec paramSpec = new PBEParameterSpec(salt, n);
		PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());

		//
		try {
			SecretKeyFactory keyFac = SecretKeyFactory
					.getInstance("PBEWithMD5AndDES");
			SecretKey key = keyFac.generateSecret(keySpec);

			// ma hoa
			Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
			cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
			byte[] encryptedOutput = cipher.doFinal(input.getBytes());

			// them salt vao
			BASE64Encoder encoder = new BASE64Encoder();
			String strSalt = encoder.encode(salt);
			String strEncrytedText = encoder.encode(encryptedOutput);

			encryptedText = strSalt + strEncrytedText;

			System.out.println("encrypted text: " + encryptedText);
			
			//giai ma
			String salt_Text = encryptedText.substring(0, 12);
			String encrypt_Text = encryptedText.substring(12);
			
			BASE64Decoder decoder = new BASE64Decoder();
			
			byte[] saltArray = decoder.decodeBuffer(salt_Text);
			byte[] textArray = decoder.decodeBuffer(encrypt_Text);
			
			PBEKeySpec keySpec2 = new PBEKeySpec(password.toCharArray());
			SecretKeyFactory keyFactory2 = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
			SecretKey key2 = keyFactory2.generateSecret(keySpec2);
			PBEParameterSpec paramSpec2 = new PBEParameterSpec(saltArray, n);
			
			Cipher cipher2 = Cipher.getInstance("PBEWithMD5AndDES");
			cipher2.init(Cipher.DECRYPT_MODE, key2, paramSpec2);
			
			byte[] plainText = cipher2.doFinal(textArray);
			
			System.out.println("plain text: " + new String(plainText));
			
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (InvalidAlgorithmParameterException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}
